/**
 * 
 */
package com.ztesoft.web.baseconfig.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.ztesoft.core.common.Page;
import com.ztesoft.core.convert.IArgConversionService;
import com.ztesoft.core.db.ds.DynamicDataSourceManager;
import com.ztesoft.core.idproduce.ISequenceGenerator;
import com.ztesoft.framework.exception.BaseAppException;
import com.ztesoft.framework.log.ZTEsoftLogManager;
import com.ztesoft.framework.util.JsonUtil;
import com.ztesoft.framework.util.Utils;
import com.ztesoft.web.baseconfig.db.arg.DmSrcTableArg;
import com.ztesoft.web.baseconfig.db.arg.DmSrcTableArg.DmSrcTableCriteria;
import com.ztesoft.web.baseconfig.db.arg.DmTargetTableArg;
import com.ztesoft.web.baseconfig.db.arg.DmTargetTableArg.DmTargetTableCriteria;
import com.ztesoft.web.baseconfig.db.arg.SubTableDefineArg;
import com.ztesoft.web.baseconfig.db.arg.SubTableDefineArg.SubTableDefineCriteria;
import com.ztesoft.web.baseconfig.db.arg.TargetColMapArg;
import com.ztesoft.web.baseconfig.db.arg.TargetColMapArg.TargetColMapCriteria;
import com.ztesoft.web.baseconfig.db.dao.DmSrcTableDao;
import com.ztesoft.web.baseconfig.db.dao.DmTargetTableDao;
import com.ztesoft.web.baseconfig.db.dao.SubTableDefineDao;
import com.ztesoft.web.baseconfig.db.dao.TargetColMapDao;
import com.ztesoft.web.baseconfig.db.po.ColumnNamePO;
import com.ztesoft.web.baseconfig.db.po.ColumnsRelationPO;
import com.ztesoft.web.baseconfig.db.po.DmSrcTablePO;
import com.ztesoft.web.baseconfig.db.po.DmStrategyPO;
import com.ztesoft.web.baseconfig.db.po.DmTargetTablePO;
import com.ztesoft.web.baseconfig.db.po.SubTableDefinePO;
import com.ztesoft.web.baseconfig.db.po.SubTablePO;
import com.ztesoft.web.baseconfig.db.po.TableNamePO;
import com.ztesoft.web.baseconfig.db.po.TargetColMapPO;
import com.ztesoft.web.baseconfig.db.po.TargetTablePO;
import com.ztesoft.web.baseconfig.service.IDmSrcTableService;
import com.ztesoft.web.baseconfig.service.IDmTargetTableService;
import com.ztesoft.web.baseconfig.service.ISubTableDefineService;
import com.ztesoft.web.baseconfig.service.ITargetColMapService;
import com.ztesoft.web.common.DMSConstant.Status;
import com.ztesoft.web.syncbaseinfo.service.BaseInfoService;

/**
 * <Description> <br>
 * 
 * @author codeCreater<br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2014年11月11日 <br>
 * @since V1.0<br>
 * @see com.ztesoft.web.baseconfig.service.impl <br>
 */

@Service("dmTargetTableService")
public class DmTargetTableServiceImpl implements IDmTargetTableService {

	private static final ZTEsoftLogManager logger = ZTEsoftLogManager.getLogger(DmTargetTableServiceImpl.class);

	@Autowired
	private DmTargetTableDao dmTargetTableDao;
	@Autowired
	private IDmSrcTableService dmSrcTableService;
	@Autowired
	private ISubTableDefineService subTableDefineService;
	@Autowired
	private ITargetColMapService targetColMapService;
	@Autowired
	private BaseInfoService baseInfoService;
	@Autowired
	private DmSrcTableDao dmSrcTableDao;
	@Autowired
	private SubTableDefineDao subTableDefineDao;
	@Autowired
	private TargetColMapDao targetColMapDao;
	@Autowired
	private DynamicDataSourceManager dynamicDataSourceManager;

	/**
	 * 查询条件转换成Arg类的服务接口
	 */
	@Resource(name = "defaultArgConversionService")
	private IArgConversionService argConversionService;

	/**
	 * 主键生成器
	 */
	@Resource(name = "sequenceProcGenerator")
	private ISequenceGenerator sequenceGenerator;

	@Override
	public List<DmTargetTablePO> selectByDmStrategyId(DmStrategyPO dsPO) throws BaseAppException {
		// 获取目标表数据
		List<DmTargetTablePO> dttPOList = dmTargetTableDao.selectBydmStrategyId(dsPO);
		SubTableDefinePO stdPO = new SubTableDefinePO();
		for (DmTargetTablePO dttPO : dttPOList) {
			stdPO.setSourceDataId(dttPO.getTargetDataId());
			stdPO.setDataType(2);
			// 设置分表数据
			dttPO.setTableNames(subTableDefineService.selectBySourceDataIdForSubAndTgt(dttPO.getTableName(), stdPO)
					.toArray(new TableNamePO[0]));
			DmSrcTablePO dstPO = dmSrcTableService.selectByPrimaryKey(dttPO.getSourceDataId());
			dttPO.setSrcTableName(dstPO.getTableName());
			dttPO.setSrcDbUserName(dstPO.getDbUserName());
			// 源表字段
			List<ColumnNamePO> srcColumnList = new ArrayList(Arrays.asList(dmSrcTableService.selectAllColumns(
					dstPO.getDbLinkId(), dstPO.getDbUserName(), dstPO.getTableName())));
			// 目标表字段
			List<ColumnNamePO> targetColumnList = new ArrayList(Arrays.asList(dmSrcTableService.selectAllColumns(
					dttPO.getDbLinkId(), dttPO.getDbUserName(), dttPO.getTableName())));
			// 去除目标表中的DM_TASK_ID和DM_DETAIL_ID字段
			for (int i = 0; i < targetColumnList.size(); i++) {
				if (targetColumnList.get(i).getColumnName().equals("dm_task_id")) {
					targetColumnList.remove(i);
					i--;
					continue;
				}
				if (targetColumnList.get(i).getColumnName().equals("dm_detail_id")) {
					targetColumnList.remove(i);
					i--;
					continue;
				}
			}
			// 已经映射好的字段
			// 先检查源或者目标的字段是否有变动，有变动的话，需要调整映射关系
			List<ColumnsRelationPO> crPOList = targetColMapService.selectByPrimaryKey(dttPO.getTargetDataId());
			Boolean hasColumn = false;
//			// 源表
//			for (int i = 0; i < crPOList.size(); i++) {
//				for (ColumnNamePO cnPO : srcColumnList) {
//					if (cnPO.getValue().equals(crPOList.get(i).getSrc())) {// 有这个字段
//						hasColumn = true;
//						break;
//					}
//				}
//				if(!hasColumn){
//					crPOList.remove(i);
//					i--;
//				}
//				hasColumn = false;
//			}
//			// 目标表
//			for (int i = 0; i < crPOList.size(); i++) {
//				for (ColumnNamePO cnPO : targetColumnList) {
//					if (cnPO.getValue().equals(crPOList.get(i).getTarget())) {// 有这个字段
//						hasColumn = true;
//						break;
//					}
//				}
//				if(!hasColumn){
//					crPOList.remove(i);
//					i--;
//				}
//				hasColumn = false;
//			}
			dttPO.setHasOkColumnsRelationPOList(crPOList);
			// 源、目标字段映射
			dttPO.setColumnsRelationPOList(getColumnsRelationList(srcColumnList, targetColumnList));
		}
		return dttPOList;
	}

	@Override
	public List<ColumnsRelationPO> getColumnsRelationList(List<ColumnNamePO> srcColumnList,
			List<ColumnNamePO> targetColumnList) throws BaseAppException {
		List<ColumnsRelationPO> resultList = new ArrayList<ColumnsRelationPO>();
		List<String> theSameColpoList = new ArrayList<String>();
		for (int i = 0; i < srcColumnList.size(); i++) {
			for (int j = 0; j < targetColumnList.size(); j++) {
				if (srcColumnList.get(i).getValue().equals(targetColumnList.get(j).getValue())) {
					theSameColpoList.add(srcColumnList.get(i).getValue());
					srcColumnList.remove(i);
					i--;
					targetColumnList.remove(j);
					j--;
					break;
				}
			}
		}
		for (int i = 0; i < theSameColpoList.size(); i++) {
			ColumnsRelationPO po = new ColumnsRelationPO();
			po.setSrc(theSameColpoList.get(i));
			po.setTarget(theSameColpoList.get(i));
			resultList.add(po);
		}
		for (int i = 0; i < srcColumnList.size(); i++) {
			ColumnsRelationPO po = new ColumnsRelationPO();
			po.setSrc(srcColumnList.get(i).getValue());
			resultList.add(po);
		}
		for (int i = 0; i < targetColumnList.size(); i++) {
			if (i >= srcColumnList.size()) {
				ColumnsRelationPO po = new ColumnsRelationPO();
				po.setTarget(targetColumnList.get(i).getValue());
				resultList.add(po);
			} else {
				resultList.get(i + theSameColpoList.size()).setTarget(targetColumnList.get(i).getValue());
			}
		}
		return resultList;
	}

	@Override
	public List<DmTargetTablePO> selectByTableName(DmTargetTablePO record) throws BaseAppException {
		DmTargetTableArg arg = new DmTargetTableArg();
		DmTargetTableCriteria criteria = arg.createCriteria();
		criteria.andTableNameEqualTo(record.getTableName());
		criteria.andDbLinkIdEqualTo(record.getDbLinkId());
		criteria.andDbUserNameEqualTo(record.getDbUserName());// 判断表是否配置过，增加DbUserName字段
		criteria.andStateNotEqualTo(Status.CANCELLED.toString());
		return dmTargetTableDao.selectByArg(arg);
	}

	@Override
	public List<DmTargetTablePO> selectByTableNameForShow(DmSrcTablePO record) throws BaseAppException {
		// 获取目标表数据
		// 先获取源表的目标表
		DmTargetTableArg dttArg = new DmTargetTableArg();
		DmTargetTableCriteria dttcCriteria = dttArg.createCriteria();
		dttcCriteria.andSourceDataIdEqualTo(record.getSourceDataId());
		dttcCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
		List<DmTargetTablePO> dttPOList = dmTargetTableDao.selectByArg(dttArg);
		// 设置srcDbLinkId
		for (DmTargetTablePO dttPO : dttPOList) {
			// 需要根据从表的源表
			dttPO.setSrcDbLinkId(record.getDbLinkId());
			dttPO.setSrcDbUserName(record.getDbUserName());
		}
		// 再获取从表的目标表
		for (SubTablePO stPO : record.getSubTables()) {
			DmTargetTableArg dttArg_sub = new DmTargetTableArg();
			DmTargetTableCriteria dttcCriteria_sub = dttArg_sub.createCriteria();
			dttcCriteria_sub.andSourceDataIdEqualTo(stPO.getSourceDataId());
			dttcCriteria_sub.andStateNotEqualTo(Status.CANCELLED.toString());
			List<DmTargetTablePO> dttPOList_sub = dmTargetTableDao.selectByArg(dttArg_sub);
			// 设置srcDbLinkId
			for (DmTargetTablePO dttPO : dttPOList_sub) {
				dttPO.setSrcDbLinkId(stPO.getDbLinkId());
				dttPO.setSrcDbUserName(record.getDbUserName());
			}
			dttPOList.addAll(dttPOList_sub);
		}
		SubTableDefinePO stdPO = new SubTableDefinePO();
		for (DmTargetTablePO dttPO : dttPOList) {
			stdPO.setSourceDataId(dttPO.getTargetDataId());
			stdPO.setDataType(2);
			// 设置分表数据
			dttPO.setTableNames(subTableDefineService.selectBySourceDataIdForSubAndTgt(dttPO.getTableName(), stdPO)
					.toArray(new TableNamePO[0]));
			DmSrcTablePO dstPO = dmSrcTableService.selectByPrimaryKey(dttPO.getSourceDataId());
			dttPO.setSrcTableName(dstPO.getTableName());
			// 源表字段
			List<ColumnNamePO> srcColumnList = new ArrayList(Arrays.asList(dmSrcTableService.selectAllColumns(
					dstPO.getDbLinkId(), dstPO.getDbUserName(), dstPO.getTableName())));
			// 目标表字段
			List<ColumnNamePO> targetColumnList = new ArrayList(Arrays.asList(dmSrcTableService.selectAllColumns(
					dttPO.getDbLinkId(), dttPO.getDbUserName(), dttPO.getTableName())));
			// 去除DM_TASK_ID和DM_DETAIL_ID字段
			for (int i = 0; i < targetColumnList.size(); i++) {
				if (targetColumnList.get(i).getColumnName().equals("dm_task_id")) {
					targetColumnList.remove(i);
					i--;
					continue;
				}
				if (targetColumnList.get(i).getColumnName().equals("dm_detail_id")) {
					targetColumnList.remove(i);
					i--;
					continue;
				}
			}
			// 源、目标字段映射
			dttPO.setColumnsRelationPOList(getColumnsRelationList(srcColumnList, targetColumnList));
			// 已经映射好的字段
			dttPO.setHasOkColumnsRelationPOList(targetColMapService.selectByPrimaryKey(dttPO.getTargetDataId()));
		}
		return dttPOList;

	}

	@Override
	public DmTargetTablePO selectByPrimaryKey(Integer key) throws BaseAppException {
		// ///////
		// TODO 根据业务场景，设置查询条件、数据校验等

		// ///////
		return dmTargetTableDao.selectByPrimaryKey(key);
	}

	@Override
	public List<DmTargetTablePO> selectByArg(DmTargetTablePO record) throws BaseAppException {
		logger.debug("selectByArg begin...record={0}", record);

		// 第一种方式：自己创建arg，自行设置查询条件及操作符
		// DmTargetTableArg arg = new DmTargetTableArg();
		// DmTargetTableCriteria criteria = arg.createCriteria();

		// 第二种方式：利用arg转换服务，转换出arg，带上查询条件及操作符，
		// 转换后，还可以自行对arg进行设置修改
		DmTargetTableArg arg = argConversionService.invokeArg(DmTargetTableArg.class, record);

		// ///////
		// TODO 根据业务场景，设置查询条件，示例
		// if (Utils.notEmpty(record.getUserName())) {
		// criteria.andUserNameLike(record.getUserName());
		// }
		// ///////

		return dmTargetTableDao.selectByArg(arg);
	}

	@Override
	public Page<DmTargetTablePO> selectByArgAndPage(DmTargetTablePO record, Page<DmTargetTablePO> resultPage)
			throws BaseAppException {
		logger.debug("selectByArgAndPage begin...record={0}", record);

		// 第一种方式：自己创建arg，自行设置查询条件及操作符
		// DmTargetTableArg arg = new DmTargetTableArg();
		// //TODO 根据业务场景，设置查询条件，示例
		// DmTargetTableCriteria criteria = arg.createCriteria();
		// if (Utils.notEmpty(record.getUserName())) {
		// criteria.andUserNameLike(record.getUserName());
		// }

		// 第二种方式：利用arg转换服务，转换出arg，带上查询条件及操作符，
		// 转换后，还可以自行对arg进行设置修改
		DmTargetTableArg arg = argConversionService.invokeArg(DmTargetTableArg.class, record);

		resultPage = dmTargetTableDao.selectByArgAndPage(arg, resultPage);

		return resultPage;
	}

	@Override
	public DmTargetTablePO stColumnsRelation(DmTargetTablePO dttPO) throws BaseAppException {
		// 验证目标表是否存在
		dttPO.setTableNames(JsonUtil.toArray(dttPO.getTableName(), TableNamePO.class));
		String tableName = dttPO.getTableNames()[0].getValue();
		dttPO.setTableName(tableName);
		if (Utils.isEmpty(dmTargetTableDao.selectByPrimaryKey(dttPO.getTargetDataId()))) {// 用ID在数据库里查不到
			if (dttPO.getIsEdit() == 0 && selectByTableName(dttPO).size() != 0) {// 已经配置过该表
				dttPO.setSourceDataId(-1);
				return dttPO;
			}
		}
		ColumnNamePO[] allColumns = dmSrcTableService.selectAllColumns(dttPO.getDbLinkId(), dttPO.getDbUserName(),
				tableName);
		if (allColumns.length == 0) {// 所选数据库中不存在该表
			dttPO.setSourceDataId(-2);
			return dttPO;
		}
		if ("-2".equals(allColumns[0].getValue()) && "-2".equals(allColumns[0].getColumnName())) {// 所选数据库中不存在该表
			dttPO.setSourceDataId(-2);
			return dttPO;
		}
		
		// 检查表里有没有DM_TASK_ID和DM_DETAIL_ID字段
		// 如果没有，则提示用户配置
		// 如果有，则不显示这两个字段
		boolean hasTaskId = false;
		boolean hasDetailId = false;
		List<ColumnNamePO> allColumnsList = new ArrayList<ColumnNamePO>();
		for (int i = 0; i < allColumns.length; i++) {
			if (allColumns[i].getColumnName().equals("dm_task_id")) {
				hasTaskId = true;
			} else if (allColumns[i].getColumnName().equals("dm_detail_id")) {
				hasDetailId = true;
			} else {
				allColumnsList.add(allColumns[i]);
			}
		}
		if (hasTaskId && hasDetailId) {// 存在这两个字段
			allColumns = allColumnsList.toArray(new ColumnNamePO[0]);
		} else {
			dttPO.setSourceDataId(-3);
			return dttPO;
		}
		
		dttPO.setAllColumns(allColumns);

		// 源字段
		List<ColumnNamePO> srcpoList = new ArrayList<ColumnNamePO>(Arrays.asList(dmSrcTableService.selectAllColumns(
				dttPO.getSrcDbLinkId(), dttPO.getSrcDbUserName(), dttPO.getSrcTableName())));
		// 目标字段
		List<ColumnNamePO> targetpoList = new ArrayList<ColumnNamePO>(Arrays.asList(dmSrcTableService.selectAllColumns(
				dttPO.getDbLinkId(), dttPO.getDbUserName(), tableName)));
		int targetColNum = targetpoList.size();
		// 源、目标一样的字段
		List<String> theSameColpoList = new ArrayList<String>();
		for (int i = 0; i < srcpoList.size(); i++) {
			for (int j = 0; j < targetpoList.size(); j++) {
				if (srcpoList.get(i).getValue().equals(targetpoList.get(j).getValue())) {
					theSameColpoList.add(srcpoList.get(i).getValue());
					srcpoList.remove(i);
					i--;
					targetpoList.remove(j);
					j--;
					break;
				}
			}
		}
		int sameColNum = theSameColpoList.size();
		if (targetColNum == sameColNum) {// 刚好匹配
			dttPO.setColumnsRelationIsOK(1);
		} else {
			dttPO.setColumnsRelationIsOK(0);
		}
		dttPO.setColumnsRelationPOList(getColumnsRelationList(srcpoList, targetpoList));
		return dttPO;
	}

	@Override
	public DmTargetTablePO add(DmTargetTablePO record) throws BaseAppException {
		logger.debug("add begin...record={0}", record);
		/*
		 * 替换，数据库必填，前台空值，的字段的值 所有非空字段： 不需要替换： 需要替换：
		 */
		// if (Utils.isEmpty(record.getIndexAnalyseFlag())) {
		// record.setIndexAnalyseFlag(DMSConstant.DONT_ANALYSE);
		// }
		// 通过前台传回来的ID，从数据库里找，是否已经有这条数据了
		Date nowDate = new Date();
		record.setStateDate(nowDate);
		DmTargetTablePO dttPO = dmTargetTableDao.selectByPrimaryKey(record.getTargetDataId());
		if (Utils.isEmpty(dttPO)) {// 不存在这条记录，说明是新增
			// 查找是否存在相同的表
			DmTargetTableArg arg = new DmTargetTableArg();
			DmTargetTableCriteria criteria = arg.createCriteria();
			criteria.andTableNameEqualTo(record.getTableName());
			if (Utils.notEmpty(record.getDbLinkId())) {
				criteria.andDbLinkIdEqualTo(record.getDbLinkId());
			}
			criteria.andDbUserNameEqualTo(record.getDbUserName());// 判断表是否配置过，增加DbUserName字段
			criteria.andStateNotEqualTo(Status.CANCELLED.toString());
			List<DmTargetTablePO> dttPOList = dmTargetTableDao.selectByArg(arg);
			if (dttPOList.size() == 0) {// 存在相同表名的记录，不可以保存
				record.setCreateDate(nowDate);
				dmTargetTableDao.insertSelective(record);
			}
		} else {
			if (dttPO.getState().equals(Status.DRAFT.toString())) {// 草稿箱，点击提交
				// 草稿箱状态为00D或者0DA，直接修改草稿箱，状态改为00A
				dmTargetTableDao.updateByPrimaryKeySelective(record);
			} else {// 修改，点击提交
				// 先把原来的记录状态改成00X
				dttPO.setState(Status.CANCELLED.toString());
				dttPO.setStateDate(nowDate);
				dmTargetTableDao.updateByPrimaryKeySelective(dttPO);
				// 再新增一条序号为 +1 的记录
				record.setSeqNbr(dttPO.getSeqNbr() + 1);
				record.setCreateDate(dttPO.getCreateDate());
				dmTargetTableDao.insertSelective(record);
			}
		}
		return record;
	}

	@Override
	public int addForDraft(DmTargetTablePO record, String state) throws BaseAppException {
		logger.debug("add begin...record={0}", record);
		Date nowDate = new Date();
		// 获取主键，目标表主键
		int targetDataId = 0;
		// 主键 生成器，获取分表定义表ID
		int subTableDefineId = 0;

		List<TargetTablePO> targetTablePOList = record.getTargetTables();
		List<Object> targetColMapList = record.getTargetColMapList();
		for (int i = 0; i < targetTablePOList.size(); i++) {
			// 目标表
			targetDataId = sequenceGenerator.sequenceIntValue("DM_TARGET_TABLE", "TARGET_DATA_ID");
			record.setTargetDataId(targetDataId);
			// 根据源数据表名，找出源id
			DmSrcTablePO dstPO = dmSrcTableDao.selectByTableName(targetTablePOList.get(i).getSrcTableName());
			record.setSourceDataId(dstPO.getSourceDataId());
			record.setSeqNbr(1);
			record.setDbLinkId(targetTablePOList.get(i).getTargetTableDbLinkId());
			record.setDbUserName(targetTablePOList.get(i).getTargetDbUserName());
			TableNamePO[] targetTableNames = targetTablePOList.get(i).getTargetTableNamePO();
			record.setTableName(targetTableNames[0].getValue());
			if (targetTableNames.length > 1) {// 存在分表
				record.setSubFlag("T");
				// 分表定义表
				for (int j = 0; j < targetTableNames.length; j++) {
					SubTableDefinePO stdPO = new SubTableDefinePO();
					subTableDefineId = sequenceGenerator.sequenceIntValue("SUB_TABLE_DEFINE", "DATA_ID");
					stdPO.setDataId(subTableDefineId);
					stdPO.setSeqNbr(1);
					stdPO.setDataType(2);
					stdPO.setPriority(j + 1);
					if ("variable".equals(targetTableNames[j].getType())) {
						stdPO.setSubDefineType(1);// 可变
						String[] timerStrs = targetTableNames[j].getValue().split(",");
						if ("0".equals(timerStrs[1])) {// 与主表字段一样
							stdPO.setSubDefineValue(timerStrs[0]);
						} else {
							stdPO.setSubDefineValue(timerStrs[1]);
						}
						stdPO.setSubRefCol(timerStrs[0]);
					} else {
						stdPO.setSubDefineType(0);// 固定
						stdPO.setSubDefineValue(targetTableNames[j].getValue());
					}
					stdPO.setSourceDataId(targetDataId);
					stdPO.setStaffId(record.getStaffId());
					stdPO.setState(state);
					stdPO.setStateDate(nowDate);
					stdPO.setCreateDate(nowDate);
					subTableDefineDao.insertSelective(stdPO);
				}
			} else {
				record.setSubFlag("F");
			}
			record.setOneRecordSize(100);// 单条记录长度，待定
			record.setStaffId(record.getStaffId());
			record.setState(state);
			record.setStateDate(nowDate);
			record.setCreateDate(nowDate);
			record.setCanDataRecovery(targetTablePOList.get(i).getCanDataRecovery());
			dmTargetTableDao.insertSelective(record);

			for (int j = 0; j < targetColMapList.size(); j++) {
				List<Object> targetColMaps = (ArrayList<Object>) targetColMapList.get(j);
				if (("" + (i + 1)).equals(targetColMaps.get(0).toString())) {
					for (int k = 1; k < targetColMaps.size(); k++) {
						// 目标字段映射
						TargetColMapPO tcmPO = new TargetColMapPO();
						tcmPO.setTargetDataId(targetDataId);
						tcmPO.setSourceDataId(dstPO.getSourceDataId());
						tcmPO.setSeqNbr(k);
						String[] columnArray = targetColMaps.get(k).toString().split(",");
						tcmPO.setSourceColumnType(1);// 源表字段的类型，待定啊，这个不懂
						if ("NORMAL_".equals(columnArray[0])) {
							tcmPO.setSourceColFlag("T");
							tcmPO.setSourceColumn(columnArray[1]);
							tcmPO.setTargetColumn(columnArray[2]);
						} else if ("INPUT_".equals(columnArray[0])) {
							tcmPO.setSourceColFlag("F");
							tcmPO.setTargetColumn(columnArray[1]);
							tcmPO.setTargetColVal(columnArray[2]);
						}
						tcmPO.setStaffId(record.getStaffId());
						tcmPO.setState(state);
						tcmPO.setStateDate(nowDate);
						tcmPO.setCreateDate(nowDate);
						targetColMapDao.insertSelective(tcmPO);
					}
				}
			}
		}
		return 1;
	}

	/**
	 * 验证表名是否存在，返回字段
	 */
	@Override
	public ColumnNamePO[] selectTableName(DmSrcTablePO record, boolean isSubTable, boolean hasSubTable)
			throws BaseAppException {
		List<ColumnNamePO> resultList = new ArrayList<ColumnNamePO>();
		String tableName = "";
		if (isSubTable) {
			TableNamePO[] tableNames = record.getSubTableNameArray();
			tableName = tableNames[0].getValue();
		} else {
			if (hasSubTable) {
				TableNamePO[] tableNames = record.getTableNameArray();
				tableName = tableNames[0].getValue();
			} else {
				tableName = record.getTableName();
			}
		}
		if (Utils.notEmpty(dmTargetTableDao.selectByTableName(tableName))) {
			ColumnNamePO po = new ColumnNamePO();
			po.setValue("1");
			po.setColumnName("2");
			resultList.add(po);
		} else {
			// DbcpConfig cbcpConfig = new DbcpConfig(DBType.MYSQL);
			// cbcpConfig.setUrl("jdbc:mysql://10.45.44.251:3306/clean");
			// cbcpConfig.setUsername("mysql");
			// cbcpConfig.setPassword("mysql");
			// cbcpConfig.setValidationQuery("SELECT 1  ");
			//
			// JdbcTemplate jdbcTemplate;
			try {
				// jdbcTemplate = new
				// JdbcTemplate(dynamicDataSourceManager.getDataSourcePoolByPoolId("mysql",
				// cbcpConfig));
				String[] dbConfig = null;
				DataSource ds = null;
				dbConfig = baseInfoService.getDbConfig(record.getDbLinkId(), record.getDbUserName());
				ds = dynamicDataSourceManager
						.getDruidDataSource(record.getDbLinkId() + record.getDbUserName(), dbConfig);
				JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
				String sql = "select column_name from information_schema.columns WHERE table_name = '" + tableName
						+ "'";
				List<Map<String, Object>> retList = jdbcTemplate.queryForList(sql);
				for (Map<String, Object> entityMap : retList) {
					ColumnNamePO po = new ColumnNamePO();
					po.setValue(entityMap.get("column_name").toString());
					po.setColumnName(entityMap.get("column_name").toString());
					resultList.add(po);
				}
			} catch (Exception e) {
				ColumnNamePO po = new ColumnNamePO();
				po.setValue("3");
				po.setColumnName("4");
				resultList.add(po);
			}
		}
		return resultList.toArray(new ColumnNamePO[0]);
	}

	@Override
	public int update(DmTargetTablePO record) throws BaseAppException {
		logger.debug("update begin...record={0}", record);

		// ///////
		// TODO 根据业务场景，进行重名校验、数据有效性校验、设置属性默认值等

		// ///////

		return dmTargetTableDao.updateByPrimaryKeySelective(record);
	}

	@Override
	public int delete(DmTargetTablePO record) throws BaseAppException {
		logger.debug("delete begin...record={0}", record);
		int staffId = record.getStaffId();
		dmTargetTableDao.updateTo00X(record.getTargetDataId());
		record.setSeqNbr(record.getSeqNbr() + 1);
		record.setStaffId(staffId);
		record.setState(Status.CANCELLED.toString());
		record.setStateDate(new Date());
		return dmTargetTableDao.insertSelective(record);
	}

	@Override
	public List<TargetTablePO> addWithOther(DmTargetTablePO record, String state) throws BaseAppException, Exception {
		logger.debug("保存目标数据以及其他相关数据----目标数据={0}", record);
		Date nowDate = new Date();
		Date createDate = new Date();
		// 获取主键，目标表主键
		int targetDataId = 0;
		// 主键 生成器，获取分表定义表ID
		int subTableDefineId = 0;

		List<TargetTablePO> targetTablePOList = record.getTargetTables();
		List<Object> targetColMapList = record.getTargetColMapList();
		for (int i = 0; i < targetTablePOList.size(); i++) {
			if (Utils.notEmpty(targetTablePOList.get(i).getIsDelete()) && targetTablePOList.get(i).getIsDelete() == 1) {// 删除的目标表
				if (targetTablePOList.get(i).getSourceDataId() == 0) {// 新建时删除的从表目标表
					continue;
				}
				// 查询参数
				DmTargetTableArg arg = new DmTargetTableArg();
				DmTargetTableCriteria criteria = arg.createCriteria();
				criteria.andSourceDataIdEqualTo(targetTablePOList.get(i).getSourceDataId());
//				criteria.andStateNotEqualTo(Status.CANCELLED.toString());
				// 目标表
				DmTargetTablePO dttPO = dmTargetTableDao.selectByArg(arg).get(0);
				dttPO.setStaffId(record.getStaffId());
				delete(dttPO);
				// 分表定义
				SubTableDefinePO stdPO = new SubTableDefinePO();
				stdPO.setSourceDataId(dttPO.getTargetDataId());
				stdPO.setStaffId(record.getStaffId());
				subTableDefineService.delete(stdPO);
				// 目标字段映射
				TargetColMapPO tcmPO = new TargetColMapPO();
				tcmPO.setTargetDataId(dttPO.getTargetDataId());
				targetColMapService.delete(tcmPO);
				continue;
			}
			// 目标表
			if (targetTablePOList.get(i).getTargetDataId() == null || targetTablePOList.get(i).getTargetDataId() == 0) {
				targetDataId = sequenceGenerator.sequenceIntValue("DM_TARGET_TABLE", "TARGET_DATA_ID");
				targetTablePOList.get(i).setTargetDataId(targetDataId);
			}
			record.setTargetDataId(targetTablePOList.get(i).getTargetDataId());
			// 根据源数据表名和数据库信息，找出源id
			DmSrcTableArg dstArg = new DmSrcTableArg();
			DmSrcTableCriteria dstCriteria = dstArg.createCriteria();
			dstCriteria.andTableNameEqualTo(targetTablePOList.get(i).getSrcTableName().trim());
			dstCriteria.andDbUserNameEqualTo(targetTablePOList.get(i).getSrcDbUserName());// 判断表是否配置过，增加DbUserName字段
			dstCriteria.andDbLinkIdEqualTo(targetTablePOList.get(i).getSrcDbLinkId());// 数据库ID传错了？
			dstCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
			DmSrcTablePO dstPO = dmSrcTableDao.selectByArg(dstArg).get(0);
			record.setSourceDataId(dstPO.getSourceDataId());
			record.setSeqNbr(1);
			record.setDbLinkId(targetTablePOList.get(i).getTargetTableDbLinkId());
			record.setDbUserName(targetTablePOList.get(i).getTargetDbUserName());
			TableNamePO[] targetTableNames = targetTablePOList.get(i).getTargetTableNamePO();
			record.setTableName(targetTableNames[0].getValue());
			// 通过ID，从数据库里找，是否已经有这个表的分表定义信息
			SubTableDefineArg arg = new SubTableDefineArg();
			SubTableDefineCriteria criteria = arg.createCriteria();
			criteria.andSourceDataIdEqualTo(targetTablePOList.get(i).getTargetDataId());
			criteria.andStateNotEqualTo(Status.CANCELLED.toString());
			List<SubTableDefinePO> stdPOList = subTableDefineDao.selectByArg(arg);
			int seqNbr = 1;
			if (stdPOList.size() != 0) {// 已经有这个表的分表定义信息
				// 先将这些分表定义表状态改成00X
				SubTableDefinePO stdPO = new SubTableDefinePO();
				stdPO.setState(Status.CANCELLED.toString());
				stdPO.setStateDate(nowDate);
				SubTableDefineArg arg_update = new SubTableDefineArg();
				SubTableDefineCriteria criteria_update = arg_update.createCriteria();
				criteria_update.andSourceDataIdEqualTo(targetTablePOList.get(i).getTargetDataId());
				criteria_update.andSeqNbrEqualTo(stdPOList.get(0).getSeqNbr());
				subTableDefineDao.updateByArgSelective(stdPO, arg_update);
				seqNbr = stdPOList.get(0).getSeqNbr() + 1;
				createDate = stdPOList.get(0).getCreateDate();
			}
			if (targetTableNames.length > 1) {// 存在分表
				record.setSubFlag("T");
				// 分表定义表
				for (int j = 0; j < targetTableNames.length; j++) {
					SubTableDefinePO stdPO = new SubTableDefinePO();
					subTableDefineId = sequenceGenerator.sequenceIntValue("SUB_TABLE_DEFINE", "DATA_ID");
					stdPO.setDataId(subTableDefineId);
					stdPO.setSeqNbr(seqNbr);
					stdPO.setDataType(2);
					stdPO.setPriority(j + 1);
					if ("variable".equals(targetTableNames[j].getType())) {
						stdPO.setSubDefineType(1);// 可变
						String[] timerStrs = targetTableNames[j].getValue().split(",");
						if ("0".equals(timerStrs[1])) {// 与主表字段一样
							stdPO.setSubDefineValue("0");
						} else {
							stdPO.setSubDefineValue(timerStrs[1]);
						}
						stdPO.setSubRefCol(timerStrs[0]);
					} else {
						stdPO.setSubDefineType(0);// 固定
						stdPO.setSubDefineValue(targetTableNames[j].getValue());
					}
					stdPO.setSourceDataId(targetTablePOList.get(i).getTargetDataId());
					stdPO.setStaffId(record.getStaffId());
					stdPO.setState(state);
					stdPO.setStateDate(nowDate);
					stdPO.setCreateDate(createDate);
					subTableDefineService.add(stdPO);
				}
			} else {
				record.setSubFlag("F");
				SubTableDefinePO stdPO = new SubTableDefinePO();
				subTableDefineId = sequenceGenerator.sequenceIntValue("SUB_TABLE_DEFINE", "DATA_ID");
				stdPO.setDataId(subTableDefineId);
				stdPO.setSeqNbr(seqNbr);
				stdPO.setDataType(2);
				stdPO.setPriority(1);
				stdPO.setSubDefineType(0);// 固定
				stdPO.setSubDefineValue(record.getTableName());
				stdPO.setSourceDataId(targetTablePOList.get(i).getTargetDataId());
				stdPO.setStaffId(record.getStaffId());
				stdPO.setState(state);
				stdPO.setStateDate(nowDate);
				stdPO.setCreateDate(createDate);
				subTableDefineService.add(stdPO);
			}
			record.setOneRecordSize(dmSrcTableService.getRecordSize(record.getDbLinkId(), record.getDbUserName(),
					record.getTableName()));
			// 是否能够数据恢复
			record.setStaffId(record.getStaffId());
			record.setState(state);
			record.setCanDataRecovery(targetTablePOList.get(i).getCanDataRecovery());
			add(record);

			// 查找字段类型
			Map<String, Integer> columnDataTypeMap = dmSrcTableService.findDataType(record.getDbLinkId(),
					record.getDbUserName(), record.getTableName());
			for (int j = 0; j < targetColMapList.size(); j++) {
				if (targetColMapList.get(j) == null || targetColMapList.get(j).equals(false)) {
					continue;
				}
				List<Object> targetColMaps = (ArrayList<Object>) targetColMapList.get(j);
				if (("" + (i + 1)).equals(targetColMaps.get(0).toString())) {
					TargetColMapArg tcmArg = new TargetColMapArg();
					TargetColMapCriteria tcmCriteria = tcmArg.createCriteria();
					tcmCriteria.andTargetDataIdEqualTo(targetTablePOList.get(i).getTargetDataId());
					tcmCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
					List<TargetColMapPO> tcmPOList = targetColMapDao.selectByArg(tcmArg);
					if (tcmPOList.size() != 0) {
						// 暂时先改成删除
						// TargetColMapPO tcmPO = new TargetColMapPO();
						// tcmPO.setState(Status.CANCELLED.toString());
						// TargetColMapArg tcmArg_update = new
						// TargetColMapArg();
						// TargetColMapCriteria tcmCriteria_update =
						// tcmArg_update.createCriteria();
						// tcmCriteria_update.andTargetDataIdEqualTo(targetTablePOList.get(i).getTargetDataId());
						// targetColMapDao.updateByArgSelective(tcmPO,
						// tcmArg_update);

						TargetColMapArg tcmArg_update = new TargetColMapArg();
						TargetColMapCriteria tcmCriteria_update = tcmArg_update.createCriteria();
						tcmCriteria_update.andTargetDataIdEqualTo(targetTablePOList.get(i).getTargetDataId());
						targetColMapDao.deleteByArg(tcmArg_update);
					}
					for (int k = 1; k < targetColMaps.size(); k++) {
						// 目标字段映射
						TargetColMapPO tcmPO = new TargetColMapPO();
						tcmPO.setTargetDataId(targetTablePOList.get(i).getTargetDataId());
						tcmPO.setSourceDataId(dstPO.getSourceDataId());
						tcmPO.setSeqNbr(k);
						String[] columnArray = targetColMaps.get(k).toString().split(",");
						if ("NORMAL_".equals(columnArray[0])) {
							tcmPO.setSourceColumnType(columnDataTypeMap.get(columnArray[2]));
							tcmPO.setSourceColFlag("T");
							tcmPO.setSourceColumn(columnArray[1]);
							tcmPO.setTargetColumn(columnArray[2]);
						} else if ("INPUT_".equals(columnArray[0])) {
							tcmPO.setSourceColumnType(columnDataTypeMap.get(columnArray[1]));
							tcmPO.setSourceColFlag("F");
							tcmPO.setTargetColumn(columnArray[1]);
							tcmPO.setTargetColVal(columnArray[2]);
						}
						tcmPO.setStaffId(record.getStaffId());
						tcmPO.setState(state);
						tcmPO.setStateDate(nowDate);
						tcmPO.setCreateDate(nowDate);
						targetColMapDao.insertSelective(tcmPO);// 有个问题，序号没有+1，主键冲突
					}
				}
			}
		}
		return targetTablePOList;
	}

	@Override
	public List<DmTargetTablePO> selectByDmPlanId(Integer dmPlanId) throws BaseAppException {
		return dmTargetTableDao.selectByDmPlanId(dmPlanId);
	}

	@Override
	public DmTargetTablePO selectBySourceId(Integer sourceDataId) throws BaseAppException {
		return dmTargetTableDao.selectBySourceId(sourceDataId);
	}
}
